package org.example.client8000.controller;

import com.alibaba.fastjson.JSONObject;
import org.example.SystemDemo.comment.res.*;
import org.example.client8000.util.StringManipulation;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import oshi.SystemInfo;
import oshi.hardware.*;
import oshi.software.os.OSProcess;
import oshi.software.os.OperatingSystem;
import oshi.util.FormatUtil;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping(value = "/StaticInfo")
public class StaticInformationController {

    /**
     * 系统版本
     */
    @RequestMapping(value = "/getSystemVersion", method = RequestMethod.GET)
    public SystemVersionRESP getSystemVersion(){
        SystemInfo si = new SystemInfo();
        OperatingSystem os =  si.getOperatingSystem();
        HardwareAbstractionLayer hal = si.getHardware();
        CentralProcessor.ProcessorIdentifier pi = hal.getProcessor().getProcessorIdentifier();

        SystemVersionRESP systemVersionRESP = new SystemVersionRESP();
        DecimalFormat df = new DecimalFormat("0.00");

        systemVersionRESP.setHostName(os.getNetworkParams().getHostName());
        systemVersionRESP.setOperatingSystemVersion(os.getFamily() + os.getVersionInfo().getVersion());
        systemVersionRESP.setProcessor(pi.getName() + " " + (double) (Math.round((Double.valueOf(pi.getVendorFreq())/ 1000000000)*100))/100  + "GHz");
        systemVersionRESP.setMemory(df.format(Double.valueOf(hal.getMemory().getTotal())/ (1024*1024*1024)) + "GB");
        systemVersionRESP.setBitness(String.valueOf(os.getBitness()));

        return systemVersionRESP;
    }

    /**
     *内核信息
     */
    @RequestMapping(value = "/getCoreInfo", method = RequestMethod.GET)
    public CoreInfoRESP getCoreInfo() {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        CentralProcessor cp = hal.getProcessor();

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        CoreInfoRESP coreInfoRESP = new CoreInfoRESP();

        coreInfoRESP.setCoreNum((cp.getLogicalProcessors().get(cp.getLogicalProcessorCount()-1).getPhysicalProcessorNumber() + 1) + "核");
        coreInfoRESP.setCpuName(cp.getProcessorIdentifier().getName());
        coreInfoRESP.setCpuNum(cp.getLogicalProcessorCount());
        coreInfoRESP.setPhysicalProcessCount(cp.getPhysicalPackageCount());
        coreInfoRESP.setClientTime(df.format(new Date()));
        coreInfoRESP.setCpuRunTime(FormatUtil.formatElapsedSecs(si.getOperatingSystem().getSystemUptime()));



        return coreInfoRESP;
    }

    /**
     * ip地址信息
     */
    @RequestMapping(value = "/getIpLocation", method = RequestMethod.GET)
    public List<IpLocationRESP> getIpLocation() {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        List<NetworkIF> NetworkIFList = hal.getNetworkIFs();


        List<IpLocationRESP> ipLocationRESPS = new ArrayList<IpLocationRESP>();


        for (NetworkIF nif: NetworkIFList) {
            IpLocationRESP ipLocationRESP = new IpLocationRESP();

            ipLocationRESP.setNetName(nif.getDisplayName());
            ipLocationRESP.setNetIfAlias(nif.getIfAlias());
            ipLocationRESP.setNetSpeed(nif.getSpeed() /1000000 + "Mbps");
            ipLocationRESP.setMTU(nif.getMTU());
            ipLocationRESP.setIfOperStatus(String.valueOf(nif.getIfOperStatus()));
            ipLocationRESP.setMacAddr(nif.getMacaddr());
            ipLocationRESP.setIpv4Addr(StringManipulation.strip(nif.getIPv4addr()));
            ipLocationRESP.setIpv6Addr(StringManipulation.strip(nif.getIPv6addr()));
            ipLocationRESP.setPacketsRecv(nif.getPacketsRecv());
            ipLocationRESP.setBytesRecv(FormatUtil.formatBytes(nif.getBytesRecv()));
            ipLocationRESP.setInErrors(nif.getInErrors());
            ipLocationRESP.setPacketsSent(nif.getPacketsSent());
            ipLocationRESP.setBytesSent(FormatUtil.formatBytes(nif.getBytesSent()));
            ipLocationRESP.setOutErrors(nif.getOutErrors());



            ipLocationRESPS.add(ipLocationRESP);
        }


        return ipLocationRESPS;
    }

    /**
     * 内存信息
     */
    @RequestMapping(value = "/getMemoryInfo", method = RequestMethod.GET)
    public MemoryInfoRESP getMemoryInfo() {
        SystemInfo si = new SystemInfo();
        GlobalMemory gm = si.getHardware().getMemory();
        System.out.println("gm:" + gm.getPhysicalMemory());

        MemoryInfoRESP memoryInfoRESP = new MemoryInfoRESP();
        List<MemoryChipsInfoRESP> memoryChipsInfoRESPSList = new ArrayList<>();
        List<PhysicalMemory> pmList = gm.getPhysicalMemory();


        memoryInfoRESP.setMemory(String.format("%.2f", Double.valueOf(gm.getTotal())/ (1024*1024*1024)) + "GB");
        memoryInfoRESP.setAvailable(String.format("%.2f", Double.valueOf(gm.getAvailable())/ (1024*1024*1024)) + "GB");
        memoryInfoRESP.setActualMemory(String.format("%.2f", Double.valueOf(gm.getTotal() - gm.getAvailable())/ (1024*1024*1024)) + "GB");
        memoryInfoRESP.setMemoryUsage(String.format("%.2f", (1 - Double.valueOf(gm.getAvailable()) / gm.getTotal()) * 100) + "%");
        memoryInfoRESP.setMemoryNum(pmList.size());

        for(PhysicalMemory pm : pmList) {
            MemoryChipsInfoRESP memoryChipsInfoRESP = new MemoryChipsInfoRESP();

            memoryChipsInfoRESP.setMemoryType(pm.getMemoryType());
            memoryChipsInfoRESP.setMemoryCapacity(FormatUtil.formatBytes(pm.getCapacity()));
            memoryChipsInfoRESP.setMemoryFrequency(FormatUtil.formatHertz(pm.getClockSpeed()));
            memoryChipsInfoRESP.setMemoryManufacturer(pm.getManufacturer());

            memoryChipsInfoRESPSList.add(memoryChipsInfoRESP);
        }

        memoryInfoRESP.setMemoryChipsInfoRESPList(memoryChipsInfoRESPSList);

        return memoryInfoRESP;
    }

    /**
     * 磁盘信息
     */
    @RequestMapping(value = "/getDiskInfo", method = RequestMethod.GET)
    public List<DiskInfoRESP> getDiskInfo() {
        SystemInfo si = new SystemInfo();
        List<HWDiskStore> ds = si.getHardware().getDiskStores();

        List<DiskInfoRESP> diskInfoRESPList = new ArrayList<DiskInfoRESP>();

        for(HWDiskStore disk : ds) {
            boolean readWrite = disk.getReads() > 0 || disk.getWrites() > 0;
            if(readWrite) {
                DiskInfoRESP diskInfoRESP = new DiskInfoRESP();
                diskInfoRESP.setDiskName(disk.getName());
                diskInfoRESP.setDiskModel(disk.getModel());
                diskInfoRESP.setDiskSerial(disk.getSerial());
                diskInfoRESP.setDiskSize(FormatUtil.formatBytesDecimal(disk.getSize()));
                diskInfoRESP.setDiskReads(disk.getReads() + " (" + FormatUtil.formatBytes(disk.getReadBytes()) + ")");
                diskInfoRESP.setDiskWrites(disk.getWrites() + " (" + FormatUtil.formatBytes(disk.getWriteBytes()) + ")");
                diskInfoRESP.setDiskTransferTime(disk.getTransferTime() + "ms");

                List<HWPartition> ptList = disk.getPartitions();
                if(ptList == null){
                    continue;
                }
                List<DiskPartitionInfoRESP> diskPartitionInfoRESPList = new ArrayList<DiskPartitionInfoRESP>();
                for(HWPartition hwp : ptList) {
                    DiskPartitionInfoRESP diskPartitionInfoRESP = new DiskPartitionInfoRESP();

                    diskPartitionInfoRESP.setDiskPartitionIdentification(hwp.getIdentification());
                    diskPartitionInfoRESP.setDiskPartitionName(hwp.getName());
                    diskPartitionInfoRESP.setDiskPartitionType(hwp.getType());
                    diskPartitionInfoRESP.setDiskPartitionMajor(hwp.getMajor());
                    diskPartitionInfoRESP.setDiskPartitionMinor(hwp.getMinor());
                    diskPartitionInfoRESP.setDiskPartitionSize(FormatUtil.formatBytesDecimal(hwp.getSize()));
                    diskPartitionInfoRESP.setDiskPartitionMountPoint(hwp.getMountPoint());

                    diskPartitionInfoRESPList.add(diskPartitionInfoRESP);
                }

                diskInfoRESP.setDiskPartitionInfoRESP(diskPartitionInfoRESPList);

                diskInfoRESPList.add(diskInfoRESP);
            }
        }

        return diskInfoRESPList;
    }
}
